package com.smart.community.region.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.community.commons.cache.DataScopeInfo;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.commons.exception.BusinessException;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.commons.utils.StringUtils;
import com.smart.community.feign.property.service.DataScopeFeign;
import com.smart.community.region.dto.BuildingDTO;
import com.smart.community.region.dto.BuildingQueryDTO;
import com.smart.community.region.entity.Building;
import com.smart.community.region.entity.Community;
import com.smart.community.region.entity.Unit;
import com.smart.community.region.entity.Household;
import com.smart.community.region.mapper.BuildingMapper;
import com.smart.community.region.mapper.UnitMapper;
import com.smart.community.region.service.CommunityCacheService;
import com.smart.community.region.service.IBuildingService;
import com.smart.community.region.mapper.CommunityMapper;
import com.smart.community.region.mapper.HouseholdMapper;
import com.smart.community.region.vo.BuildingVO;
import com.smart.community.region.vo.CommunityVO;

import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;

/**
 * 楼栋管理服务实现类 根据《智慧社区微服务架构总览.md》权威标准实现数据权限控制
 *
 * @author Wu.Liang
 * @since 2024-12-21
 */
@Slf4j
@Service
public class BuildingServiceImpl extends ServiceImpl<BuildingMapper, Building> implements IBuildingService {

	@Autowired
	private CommunityMapper communityMapper;

	@Autowired
	private CommunityCacheService communityCacheService;

	@Autowired
	private DataScopeFeign dataScopeFeign;

	@Autowired
	private HouseholdMapper householdMapper;

	@Autowired
	private UnitMapper unitMapper;

	@Override
	public IPage<Building> getBuildingPage(BuildingQueryDTO queryDTO) {
		log.info("分页查询楼栋列表，查询条件：{}", queryDTO);

		try {
			// 构建查询条件
			LambdaQueryWrapper<Building> queryWrapper = new LambdaQueryWrapper<>();

			// 楼栋名称模糊查询
			if (StringUtils.isNotBlank(queryDTO.getBuildingName())) {
				queryWrapper.like(Building::getBuildingName, queryDTO.getBuildingName());
			}

			// 楼栋编号模糊查询
			if (StringUtils.isNotBlank(queryDTO.getBuildingNo())) {
				queryWrapper.like(Building::getBuildingNo, queryDTO.getBuildingNo());
			}

			// 社区ID查询
			if (queryDTO.getCommunityId() != null) {
				queryWrapper.eq(Building::getCommunityId, queryDTO.getCommunityId());
			}

			// 状态查询
			if (queryDTO.getStatus() != null) {
				queryWrapper.eq(Building::getStatus, queryDTO.getStatus());
			}

			// 应用数据权限过滤
			applyDataPermissionFilter(queryWrapper);

			// 排序
//            queryWrapper.orderByAsc(Building::getSortOrder, Building::getCreateTime);

			// 分页查询
			Page<Building> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
			return this.page(page, queryWrapper);

		} catch (Exception e) {
			log.warn("分页查询楼栋列表失败", e);
			throw new BusinessException("查询楼栋列表失败：" + e.getMessage());
		}
	}

	@Override
	public Building getBuildingDetail(Long buildingId) {
		log.info("根据ID查询楼栋详情，楼栋ID：{}", buildingId);

		try {
			Building building = this.getById(buildingId);
			if (building == null) {
				throw new BusinessException("楼栋不存在");
			}

			// 检查数据权限
			if (!hasDataPermission(building)) {
				throw new BusinessException("您没有权限访问该楼栋信息");
			}

			return building;

		} catch (Exception e) {
			log.warn("根据ID查询楼栋详情失败，楼栋ID：{}", buildingId, e);
			throw new BusinessException("查询楼栋详情失败：" + e.getMessage());
		}
	}

	@Override
	public Building getBuildingByNo(String buildingNo) {
		log.info("根据编号查询楼栋，楼栋编号：{}", buildingNo);

		try {
			Building building = baseMapper.selectByBuildingNo(buildingNo);
			if (building == null) {
				throw new BusinessException("楼栋不存在");
			}

			// 检查数据权限
			if (!hasDataPermission(building)) {
				throw new BusinessException("您没有权限访问该楼栋信息");
			}

			return building;

		} catch (Exception e) {
			log.warn("根据编号查询楼栋失败，楼栋编号：{}", buildingNo, e);
			throw new BusinessException("查询楼栋失败：" + e.getMessage());
		}
	}

	@Override
	@GlobalTransactional(rollbackFor = Exception.class)
	public boolean createBuilding(BuildingDTO buildingDTO) throws Exception {
		log.info("新增楼栋，楼栋信息：{}", buildingDTO);
		try {
			// 参数校验
			validateBuildingDTO(buildingDTO);

			// 楼栋编号不再要求唯一性，允许重复
			// 注释掉唯一性检查，符合业务实际情况

			// 检查社区是否存在
			if (buildingDTO.getCommunityId() != null) {
				Community community = communityMapper.selectById(buildingDTO.getCommunityId());
				if (community == null) {
					throw new BusinessException("社区不存在");
				}

				// 检查是否有权限在该社区创建楼栋
				if (!hasCommunityPermission(buildingDTO.getCommunityId())) {
					throw new BusinessException("您没有权限在该社区创建楼栋");
				}
			}

			// 构建楼栋实体
			Building building = new Building();
			BeanUtils.copyProperties(buildingDTO, building);

			// 确保楼栋编号不为空
			if (StringUtils.isBlank(building.getBuildingNo())) {
				throw new BusinessException("楼栋编号不能为空");
			}

			// 设置创建信息
			Long userId = SecurityUtils.getCurrentUserId();
			if (userId == null) {
				throw new BusinessException("获取当前用户信息失败");
			}
			building.setCreateBy(userId);
			building.setCreateTime(LocalDateTime.now());
			building.setUpdateBy(userId);
			building.setUpdateTime(LocalDateTime.now());
			building.setDeleted(0);
			building.setVersion(1);
			// 如果没填建筑面积，默认150吧
			if (building.getArea() == null) {
				BigDecimal defaultArea = BigDecimal.valueOf(150);
				building.setArea(defaultArea);
				building.setLandArea(defaultArea);
			}

			// 保存楼栋
			boolean result = this.save(building);
			if (result) {
				log.info("新增楼栋成功，楼栋ID：{}", building.getId());

				// 根据楼栋单元数量自动生成单元记录
				generateUnitsForBuilding(building);

				// 清除缓存
				clearBuildingCache(building.getId());
			}

			return result;

		} catch (Exception e) {
			log.warn("新增楼栋失败", e);
			throw new BusinessException("新增楼栋失败：" + e.getMessage());
		}
	}

	@Override
	@GlobalTransactional(rollbackFor = Exception.class)
	public boolean updateBuilding(BuildingDTO buildingDTO) {
		log.info("更新楼栋，楼栋信息：{}", buildingDTO);

		try {
			// 参数校验
			validateBuildingDTO(buildingDTO);

			// 检查楼栋是否存在
			Building existingBuilding = this.getById(buildingDTO.getId());
			if (existingBuilding == null) {
				throw new BusinessException("楼栋不存在");
			}

			// 检查数据权限
			if (!hasDataPermission(existingBuilding)) {
				throw new BusinessException("您没有权限修改该楼栋信息");
			}

			// 楼栋编号不再要求唯一性，允许重复
			// 注释掉唯一性检查，符合业务实际情况

			// 检查社区是否存在
			if (buildingDTO.getCommunityId() != null) {
				Community community = communityMapper.selectById(buildingDTO.getCommunityId());
				if (community == null) {
					throw new BusinessException("社区不存在");
				}

				// 检查是否有权限在该社区创建楼栋
				if (!hasCommunityPermission(buildingDTO.getCommunityId())) {
					throw new BusinessException("您没有权限在该社区创建楼栋");
				}
			}

			// 获取楼栋下现有的单元记录 - 使用mapper直接查询
			List<Unit> existingUnits = unitMapper.selectByBuildingId(buildingDTO.getId());

			// 更新楼栋信息 - 保留原有版本号，确保乐观锁正常工作
			BeanUtils.copyProperties(buildingDTO, existingBuilding, "version");

			// 设置更新信息
			Long userId = SecurityUtils.getCurrentUserId();
			if (userId == null) {
				throw new BusinessException("获取当前用户信息失败");
			}
			existingBuilding.setUpdateBy(userId);
			existingBuilding.setUpdateTime(LocalDateTime.now());

			boolean result = this.updateById(existingBuilding);
			if (result) {
				log.info("更新楼栋成功，楼栋ID：{}", existingBuilding.getId());

				// 更新单元记录
				updateUnitsForBuilding(existingBuilding, existingUnits);

				// 清除缓存
				clearBuildingCache(existingBuilding.getId());
			}

			return result;

		} catch (Exception e) {
			log.warn("更新楼栋失败", e);
			throw new BusinessException("更新楼栋失败：" + e.getMessage());
		}
	}

	@Override
	@GlobalTransactional(rollbackFor = Exception.class)
	public boolean deleteBuilding(Long buildingId) {
		log.info("删除楼栋，楼栋ID：{}", buildingId);

		try {
			// 检查楼栋是否存在
			Building building = this.getById(buildingId);
			if (building == null) {
				throw new BusinessException("楼栋不存在");
			}

			// 检查数据权限
			if (!hasDataPermission(building)) {
				throw new BusinessException("您没有权限删除该楼栋");
			}

			// 逻辑删除
			building.setDeleted(1);
			building.setUpdateBy(SecurityUtils.getCurrentUserId());
			building.setUpdateTime(LocalDateTime.now());

			boolean result = this.updateById(building);
			if (result) {
				log.info("删除楼栋成功，楼栋ID：{}", buildingId);
				// 清除缓存
				clearBuildingCache(buildingId);
			}

			return result;

		} catch (Exception e) {
			log.warn("删除楼栋失败，楼栋ID：{}", buildingId, e);
			throw new BusinessException("删除楼栋失败：" + e.getMessage());
		}
	}

	@Override
	@GlobalTransactional(rollbackFor = Exception.class)
	public boolean batchDeleteBuildings(List<Long> buildingIds) {
		log.info("批量删除楼栋，楼栋ID列表：{}", buildingIds);

		try {
			if (buildingIds == null || buildingIds.isEmpty()) {
				throw new BusinessException("楼栋ID列表不能为空");
			}

			// 检查所有楼栋的数据权限
			for (Long buildingId : buildingIds) {
				Building building = this.getById(buildingId);
				if (building == null) {
					throw new BusinessException("楼栋不存在，ID：" + buildingId);
				}

				if (!hasDataPermission(building)) {
					throw new BusinessException("您没有权限删除楼栋：" + building.getBuildingName());
				}
			}

			// 批量逻辑删除
			List<Building> buildings = this.listByIds(buildingIds);
			for (Building building : buildings) {
				building.setDeleted(1);
				building.setUpdateBy(SecurityUtils.getCurrentUserId());
				building.setUpdateTime(LocalDateTime.now());
			}

			boolean result = this.updateBatchById(buildings);
			if (result) {
				log.info("批量删除楼栋成功，楼栋ID列表：{}", buildingIds);
				// 清除缓存
				for (Long buildingId : buildingIds) {
					clearBuildingCache(buildingId);
				}
			}

			return result;

		} catch (Exception e) {
			log.warn("批量删除楼栋失败", e);
			throw new BusinessException("批量删除楼栋失败：" + e.getMessage());
		}
	}

	@Override
	public List<Building> getBuildingsByCommunity(Long communityId) {
		log.info("根据社区ID查询楼栋列表，社区ID：{}", communityId);

		try {
			// 检查社区权限
			if (!hasCommunityPermission(communityId)) {
				log.warn("用户无权限访问社区，社区ID：{}", communityId);
				return Collections.emptyList();
			}

			LambdaQueryWrapper<Building> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(Building::getCommunityId, communityId).eq(Building::getDeleted, 0)
					.orderByAsc(Building::getSortOrder, Building::getCreateTime);

			return this.list(queryWrapper);

		} catch (Exception e) {
			log.warn("根据社区ID查询楼栋列表失败，社区ID：{}", communityId, e);
			throw new BusinessException("查询楼栋列表失败：" + e.getMessage());
		}
	}

	@Override
	public List<Building> getBuildingsTreeByCommunityIds(List<Long> communityIds) {
		log.info("根据社区ID列表查询楼栋树形结构，社区ID列表：{}", communityIds);

		try {
			if (communityIds == null || communityIds.isEmpty()) {
				return Collections.emptyList();
			}

			// 过滤有权限的社区ID
			List<Long> accessibleCommunityIds = communityIds.stream().filter(this::hasCommunityPermission)
					.collect(Collectors.toList());

			if (accessibleCommunityIds.isEmpty()) {
				log.warn("用户无权限访问任何社区，社区ID列表：{}", communityIds);
				return Collections.emptyList();
			}

			LambdaQueryWrapper<Building> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.in(Building::getCommunityId, accessibleCommunityIds).eq(Building::getDeleted, 0)
					.orderByAsc(Building::getSortOrder, Building::getCreateTime);

			return this.list(queryWrapper);

		} catch (Exception e) {
			log.warn("根据社区ID列表查询楼栋树形结构失败", e);
			throw new BusinessException("查询楼栋树形结构失败：" + e.getMessage());
		}
	}

	@Override
	public List<Building> getBuildingsByCommunityIds(List<Long> communityIds, int current, int size) {
		log.info("根据社区ID列表分页查询楼栋，社区ID列表：{}，当前页：{}，每页大小：{}", communityIds, current, size);

		try {
			if (communityIds == null || communityIds.isEmpty()) {
				return Collections.emptyList();
			}

			// 过滤有权限的社区ID
			List<Long> accessibleCommunityIds = communityIds.stream().filter(this::hasCommunityPermission)
					.collect(Collectors.toList());

			if (accessibleCommunityIds.isEmpty()) {
				log.warn("用户无权限访问任何社区，社区ID列表：{}", communityIds);
				return Collections.emptyList();
			}

			LambdaQueryWrapper<Building> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.in(Building::getCommunityId, accessibleCommunityIds).eq(Building::getDeleted, 0)
					.orderByAsc(Building::getSortOrder, Building::getCreateTime);

			Page<Building> page = new Page<>(current, size);
			IPage<Building> pageResult = this.page(page, queryWrapper);

			return pageResult.getRecords();

		} catch (Exception e) {
			log.warn("根据社区ID列表分页查询楼栋失败", e);
			throw new BusinessException("查询楼栋列表失败：" + e.getMessage());
		}
	}

	@Override
	@GlobalTransactional(rollbackFor = Exception.class)
	public boolean updateBuildingStatus(Long buildingId, Integer status) {
		log.info("更新楼栋状态，楼栋ID：{}，状态：{}", buildingId, status);

		try {
			// 检查楼栋是否存在
			Building building = this.getById(buildingId);
			if (building == null) {
				throw new BusinessException("楼栋不存在");
			}

			// 检查数据权限
			if (!hasDataPermission(building)) {
				throw new BusinessException("您没有权限修改该楼栋状态");
			}

			// 更新状态
			building.setStatus(status);
			building.setUpdateBy(SecurityUtils.getCurrentUserId());
			building.setUpdateTime(LocalDateTime.now());

			boolean result = this.updateById(building);
			if (result) {
				log.info("更新楼栋状态成功，楼栋ID：{}，状态：{}", buildingId, status);
				// 清除缓存
				clearBuildingCache(buildingId);
			}

			return result;

		} catch (Exception e) {
			log.warn("更新楼栋状态失败，楼栋ID：{}，状态：{}", buildingId, status, e);
			throw new BusinessException("更新楼栋状态失败：" + e.getMessage());
		}
	}

	@Override
	@GlobalTransactional(rollbackFor = Exception.class)
	public boolean batchUpdateBuildingStatus(List<Long> buildingIds, Integer status) {
		log.info("批量更新楼栋状态，楼栋ID列表：{}，状态：{}", buildingIds, status);

		try {
			if (buildingIds == null || buildingIds.isEmpty()) {
				throw new BusinessException("楼栋ID列表不能为空");
			}

			// 检查所有楼栋的数据权限
			for (Long buildingId : buildingIds) {
				Building building = this.getById(buildingId);
				if (building == null) {
					throw new BusinessException("楼栋不存在，ID：" + buildingId);
				}

				if (!hasDataPermission(building)) {
					throw new BusinessException("您没有权限修改楼栋状态：" + building.getBuildingName());
				}
			}

			// 批量更新状态
			List<Building> buildings = this.listByIds(buildingIds);
			for (Building building : buildings) {
				building.setStatus(status);
				building.setUpdateBy(SecurityUtils.getCurrentUserId());
				building.setUpdateTime(LocalDateTime.now());
			}

			boolean result = this.updateBatchById(buildings);
			if (result) {
				log.info("批量更新楼栋状态成功，楼栋ID列表：{}，状态：{}", buildingIds, status);
				// 清除缓存
				for (Long buildingId : buildingIds) {
					clearBuildingCache(buildingId);
				}
			}

			return result;

		} catch (Exception e) {
			log.warn("批量更新楼栋状态失败", e);
			throw new BusinessException("批量更新楼栋状态失败：" + e.getMessage());
		}
	}

	@Override
	public Object getBuildingStats(Long buildingId) {
		log.info("获取楼栋统计信息，楼栋ID：{}", buildingId);

		try {
			// 检查楼栋是否存在
			Building building = this.getById(buildingId);
			if (building == null) {
				throw new BusinessException("楼栋不存在");
			}

			// 检查数据权限
			if (!hasDataPermission(building)) {
				throw new BusinessException("您没有权限查看该楼栋统计信息");
			}

			// 构建统计信息
			Map<String, Object> stats = new HashMap<>();
			stats.put("buildingInfo", building);
			stats.put("totalUnits", building.getUnitCount());
			stats.put("totalHouseholds", building.getHouseholdCount());
			stats.put("averageHouseholdsPerFloor",
					building.getFloorCount() != null && building.getFloorCount() > 0
							&& building.getHouseholdCount() != null
									? building.getHouseholdCount() / building.getFloorCount()
									: 0);

			return stats;

		} catch (Exception e) {
			log.warn("获取楼栋统计信息失败，楼栋ID：{}", buildingId, e);
			throw new BusinessException("获取楼栋统计信息失败：" + e.getMessage());
		}
	}

	@Override
	public boolean checkBuildingNoUnique(String buildingNo, Long excludeBuildingId) {
		log.info("检查楼栋编号唯一性，楼栋编号：{}，排除楼栋ID：{}", buildingNo, excludeBuildingId);

		try {
			return !baseMapper.existsByBuildingNo(buildingNo, excludeBuildingId);
		} catch (Exception e) {
			log.warn("检查楼栋编号唯一性失败，楼栋编号：{}", buildingNo, e);
			throw new BusinessException("检查楼栋编号唯一性失败：" + e.getMessage());
		}
	}

	@Override
	public Long countBuildings(Long communityId) {
		log.info("统计社区楼栋数量，社区ID：{}", communityId);

		try {
			// 检查社区权限
			if (!hasCommunityPermission(communityId)) {
				log.warn("用户无权限访问社区，社区ID：{}", communityId);
				return 0L;
			}

			LambdaQueryWrapper<Building> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(Building::getCommunityId, communityId).eq(Building::getDeleted, 0);

			return Long.valueOf(this.count(queryWrapper));

		} catch (Exception e) {
			log.warn("统计社区楼栋数量失败，社区ID：{}", communityId, e);
			throw new BusinessException("统计楼栋数量失败：" + e.getMessage());
		}
	}

	@Override
	public void clearBuildingCache(Long buildingId) {
		log.info("清除楼栋缓存，楼栋ID：{}", buildingId);
		// TODO: 实现缓存清除逻辑
	}

	@Override
	public void clearAllBuildingCache() {
		log.info("清除所有楼栋缓存");
		// TODO: 实现缓存清除逻辑
	}

	/**
	 * 应用数据权限过滤 根据《智慧社区微服务架构总览.md》权威标准实现
	 */
	private void applyDataPermissionFilter(LambdaQueryWrapper<Building> queryWrapper) {
		try {
			// 获取当前用户信息
			DataScopeInfo uds = dataScopeFeign.getUserDataScope(SecurityUtils.getCurrentUserId());

			// 超级管理员跳过数据权限过滤
			if (uds.isSuperAdmin()) {
				return;
			}

			// 获取用户可访问的社区ID集合
			List<Long> communityIds = uds.getCommunityIds();
			if (communityIds.isEmpty()) {
				queryWrapper.eq(Building::getId, -1L); // 返回空结果
				return;
			}

			// 获取用户可访问的楼栋ID集合
			List<Long> buildingIds = this.getBuildingIdsByCommunityIds(communityIds);
			if (buildingIds.isEmpty()) {
				queryWrapper.eq(Building::getId, -1L); // 返回空结果
				return;
			}

			// 应用楼栋权限过滤
			queryWrapper.in(Building::getId, buildingIds);
		} catch (Exception e) {
			log.warn("应用数据权限过滤失败", e);
			queryWrapper.eq(Building::getId, -1L); // 异常时返回空结果
		}
	}

	/**
	 * 检查用户是否有楼栋数据权限
	 */
	private boolean hasDataPermission(Building building) {
		try {
			// 获取当前用户信息
			DataScopeInfo uds = dataScopeFeign.getUserDataScope(SecurityUtils.getCurrentUserId());

			// 超级管理员拥有所有权限
			if (uds.isSuperAdmin()) {
				return true;
			}

			// 检查用户是否有关联物业公司
			if (!uds.isPropertyCompanyUser()) {
				return false;
			}

			// 获取用户可访问的社区ID集合
			List<Long> communityIds = uds.getCommunityIds();
			if (communityIds.isEmpty()) {
				return false;
			}

			// 获取用户可访问的楼栋ID集合
			List<Long> buildingIds = this.getBuildingIdsByCommunityIds(communityIds);
			if (buildingIds.isEmpty()) {
				return false;
			}

			// 检查楼栋是否在用户权限范围内
			return buildingIds.contains(building.getId());
		} catch (Exception e) {
			log.warn("检查楼栋数据权限失败", e);
			return false;
		}
	}

	/**
	 * 检查用户是否有社区权限
	 */
	private boolean hasCommunityPermission(Long communityId) {
		try {
			// 获取当前用户信息
			DataScopeInfo uds = dataScopeFeign.getUserDataScope(SecurityUtils.getCurrentUserId());

			// 超级管理员拥有所有权限
			if (uds.isSuperAdmin()) {
				return true;
			}

			// 检查用户是否有关联物业公司
			if (!uds.isPropertyCompanyUser()) {
				return false;
			}

			// 获取用户可访问的社区ID集合
			List<Long> communityIds = uds.getCommunityIds();
			if (communityIds.isEmpty()) {
				return false;
			}

			// 检查社区是否在用户权限范围内
			return communityIds.contains(communityId);
		} catch (Exception e) {
			log.warn("检查社区权限失败", e);
			return false;
		}
	}

	/**
	 * 转换为VO对象
	 */
	@Override
	public BuildingVO convertToVO(Building building) {
		if (building == null) {
			return null;
		}

		BuildingVO vo = new BuildingVO();
		BeanUtils.copyProperties(building, vo);

		// 填充社区名称
		if (building.getCommunityId() != null) {
			try {
				// 优先从缓存获取
				CommunityVO community = communityCacheService.getCommunityById(building.getCommunityId());
				if (community != null) {
					vo.setCommunityName(community.getCommunityName());
				} else {
					// 缓存中未找到，直接从数据库查询
					log.warn("缓存中未找到社区信息，直接从数据库查询，社区ID：{}", building.getCommunityId());
					try {
						Community dbCommunity = communityMapper.selectById(building.getCommunityId());
						if (dbCommunity != null) {
							vo.setCommunityName(dbCommunity.getCommunityName());
						} else {
							log.warn("数据库中未找到社区信息，社区ID：{}", building.getCommunityId());
							vo.setCommunityName("未知社区");
						}
					} catch (Exception dbException) {
						log.error("直接从数据库查询社区信息失败，社区ID：{}", building.getCommunityId(), dbException);
						vo.setCommunityName("未知社区");
					}
				}
			} catch (Exception e) {
				log.warn("获取社区信息失败，尝试直接从数据库查询，社区ID：{}", building.getCommunityId(), e);
				try {
					// 缓存服务失败时，直接从数据库查询
					Community dbCommunity = communityMapper.selectById(building.getCommunityId());
					if (dbCommunity != null) {
						vo.setCommunityName(dbCommunity.getCommunityName());
					} else {
						log.warn("数据库中未找到社区信息，社区ID：{}", building.getCommunityId());
						vo.setCommunityName("未知社区");
					}
				} catch (Exception dbException) {
					log.error("直接从数据库查询社区信息也失败，社区ID：{}", building.getCommunityId(), dbException);
					vo.setCommunityName("未知社区");
				}
			}
		}



		return vo;
	}

	/**
	 * 批量转换为VO对象（优化版本，使用批量缓存查询）
	 */
	@Override
	public List<BuildingVO> convertToVOList(List<Building> buildings) {
		if (buildings == null || buildings.isEmpty()) {
			return new ArrayList<>();
		}

		// 收集所有社区ID
		List<Long> communityIds = buildings.stream().map(Building::getCommunityId).filter(Objects::nonNull).distinct()
				.collect(Collectors.toList());

		// 批量获取社区信息
		final Map<Long, CommunityVO> communityMap = new HashMap<>();
		if (!communityIds.isEmpty()) {
			try {
				// 优先从缓存获取
				Map<Long, CommunityVO> cachedMap = communityCacheService.getCommunitiesByIds(communityIds);
				communityMap.putAll(cachedMap);
				
				// 检查是否有未获取到的社区信息
				List<Long> missingCommunityIds = communityIds.stream()
						.filter(id -> !communityMap.containsKey(id))
						.collect(Collectors.toList());
				
				// 如果有未获取到的社区信息，直接从数据库查询
				if (!missingCommunityIds.isEmpty()) {
					log.warn("缓存中未找到部分社区信息，直接从数据库查询，缺失的社区ID：{}", missingCommunityIds);
					try {
						List<Community> missingCommunities = communityMapper.selectBatchByIds(missingCommunityIds);
						for (Community community : missingCommunities) {
							CommunityVO communityVO = new CommunityVO();
							BeanUtils.copyProperties(community, communityVO);
							communityMap.put(community.getId(), communityVO);
						}
					} catch (Exception e) {
						log.error("直接从数据库查询社区信息失败，社区ID列表：{}", missingCommunityIds, e);
					}
				}
			} catch (Exception e) {
				log.warn("批量获取社区信息失败，尝试直接从数据库查询", e);
				try {
					// 缓存服务失败时，直接从数据库批量查询
					List<Community> communities = communityMapper.selectBatchByIds(communityIds);
					for (Community community : communities) {
						CommunityVO communityVO = new CommunityVO();
						BeanUtils.copyProperties(community, communityVO);
						communityMap.put(community.getId(), communityVO);
					}
				} catch (Exception dbException) {
					log.error("直接从数据库查询社区信息也失败，社区ID列表：{}", communityIds, dbException);
				}
			}
		}

		// 转换为VO
		final Map<Long, CommunityVO> finalCommunityMap = communityMap;
		return buildings.stream().map(building -> {
			BuildingVO vo = new BuildingVO();
			BeanUtils.copyProperties(building, vo);

			// 填充社区名称
			if (building.getCommunityId() != null) {
				CommunityVO community = finalCommunityMap.get(building.getCommunityId());
				if (community != null) {
					vo.setCommunityName(community.getCommunityName());
				} else {
					// 如果仍然无法获取社区信息，记录日志并设置默认值
					log.warn("无法获取社区信息，楼栋ID：{}，社区ID：{}", building.getId(), building.getCommunityId());
					vo.setCommunityName("未知社区");
				}
			}

			return vo;
		}).collect(Collectors.toList());
	}

	/**
	 * 校验楼栋DTO
	 */
	private void validateBuildingDTO(BuildingDTO buildingDTO) {
		if (buildingDTO == null) {
			throw new BusinessException("楼栋信息不能为空");
		}

		if (StringUtils.isBlank(buildingDTO.getBuildingName())) {
			throw new BusinessException("楼栋名称不能为空");
		}

		if (StringUtils.isBlank(buildingDTO.getBuildingNo())) {
			throw new BusinessException("楼栋编号不能为空");
		}

		if (StringUtils.isBlank(buildingDTO.getBuildingNo())) {
			throw new BusinessException("楼栋编号不能为空");
		}

		if (buildingDTO.getCommunityId() == null) {
			throw new BusinessException("所属社区不能为空");
		}

		if (StringUtils.isBlank(buildingDTO.getBuildingType())) {
			throw new BusinessException("建筑类型不能为空");
		}

		if (buildingDTO.getFloorCount() == null || buildingDTO.getFloorCount() <= 0) {
			throw new BusinessException("楼层数必须大于0");
		}

		if (buildingDTO.getUnitCount() == null || buildingDTO.getUnitCount() <= 0) {
			throw new BusinessException("单元数必须大于0");
		}

		// 设置每层户数默认值为2
		if (buildingDTO.getUnitsPerFloor() == null || buildingDTO.getUnitsPerFloor() <= 0) {
			buildingDTO.setUnitsPerFloor(2);
		}
	}

	// ==================== 数据权限业务接口实现 ====================

	@Override
	public List<Long> getBuildingIdsByCommunityIds(List<Long> communityIds) {
		log.info("根据社区ID集合获取楼栋ID集合，社区数量：{}", communityIds != null ? communityIds.size() : 0);
		try {
			if (communityIds == null || communityIds.isEmpty()) {
				return new ArrayList<>();
			}

			// 查询指定社区下的所有楼栋ID
			LambdaQueryWrapper<Building> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.select(Building::getId);
			queryWrapper.in(Building::getCommunityId, communityIds);
			queryWrapper.eq(Building::getDeleted, 0);

			List<Building> buildings = this.list(queryWrapper);
			List<Long> buildingIds = buildings.stream().map(Building::getId).collect(Collectors.toList());

			log.info("根据社区ID集合获取楼栋ID集合成功，社区数量：{}，楼栋数量：{}", communityIds.size(), buildingIds.size());
			return buildingIds;
		} catch (Exception e) {
			log.warn("根据社区ID集合获取楼栋ID集合失败，社区IDs：{}", communityIds, e);
			return new ArrayList<>();
		}
	}

	@Override
	public List<Long> getBuildingIdsByCommunityId(Long communityId) {
		log.info("根据社区ID获取楼栋ID列表，社区ID：{}", communityId);
		try {
			if (communityId == null) {
				return new ArrayList<>();
			}

			// 查询指定社区下的所有楼栋ID
			LambdaQueryWrapper<Building> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.select(Building::getId);
			queryWrapper.eq(Building::getCommunityId, communityId);
			queryWrapper.eq(Building::getDeleted, 0);

			List<Building> buildings = this.list(queryWrapper);
			List<Long> buildingIds = buildings.stream().map(Building::getId).collect(Collectors.toList());

			log.info("根据社区ID获取楼栋ID列表成功，社区ID：{}，楼栋数量：{}", communityId, buildingIds.size());
			return buildingIds;
		} catch (Exception e) {
			log.warn("根据社区ID获取楼栋ID列表失败，社区ID：{}", communityId, e);
			return new ArrayList<>();
		}
	}

	/**
	 * 为楼栋生成单元记录 根据楼栋单元数量自动初始化单元记录
	 */
	private void generateUnitsForBuilding(Building building) {
		try {
			int unitCount = building.getUnitCount();
			if (unitCount <= 0) {
				log.warn("楼栋单元数量为0，跳过单元生成，楼栋ID: {}", building.getId());
				return;
			}

			List<Unit> units = new ArrayList<>();
			Long currentUserId = SecurityUtils.getCurrentUserId();

			for (int i = 1; i <= unitCount; i++) {
				Unit unit = new Unit();

				// 单元编号命名规则：{序号}
				unit.setUnitNo(String.valueOf(i));

				// 单元名称命名规则：{序号}单元
				unit.setUnitName(i + "单元");

				// 单元编码：楼栋编号+单元编号
				unit.setUnitCode(building.getBuildingNo() + "-" + i);

				// 关联楼栋ID
				unit.setBuildingId(building.getId());

				// 设置所属社区ID
				unit.setCommunityId(building.getCommunityId());

				// 楼层数取楼栋的楼层数
				unit.setFloorCount(building.getFloorCount());

				// 房间数量 = 楼层数 × 每层户数
				int unitsPerFloor = building.getUnitsPerFloor() != null ? building.getUnitsPerFloor() : 2;
				unit.setRoomCount(building.getFloorCount() * unitsPerFloor);

				// 户数默认为0
				unit.setHouseholdCount(0);

				// 默认字段设置
				unit.setHasElevator(0); // 默认无电梯
				unit.setElevatorCount(0); // 默认电梯数量为0
				unit.setDoorAccessType(1); // 默认门禁类型：1-密码
				unit.setStatus(1); // 默认状态：1-启用
				unit.setCreateBy(currentUserId);
				unit.setUpdateBy(currentUserId);
				// 建筑面积除以单元数量
				double buildingArea = building.getArea().doubleValue();
				double unitArea = buildingArea / unitCount;
				unit.setArea(BigDecimal.valueOf(unitArea));
				units.add(unit);
			}

			// 批量保存单元记录 - 使用mapper直接保存
			if (!units.isEmpty()) {
				for (Unit unit : units) {
					unitMapper.insert(unit);
				}
				log.info("楼栋新增成功，已生成{}个单元记录，楼栋ID: {}", unitCount, building.getId());

				// 在单元数据增加完毕的时候，我们执行房户数据的初始化
				// 首先，最重要的是把household_code的唯一索引删除，这是重点！！！
				// 然后为每个单元生成房户数据
				int totalHouseholds = 0;
				int unitsPerFloor = building.getUnitsPerFloor() != null ? building.getUnitsPerFloor() : 2;

				for (Unit unit : units) {
					int householdCount = generateHouseholdsForUnit(unit, building.getId(),
							building.getFloorCount(), unitsPerFloor);
					totalHouseholds += householdCount;
				}

				log.info("楼栋新增成功，已为{}个单元生成{}个房户记录，楼栋ID: {}", unitCount, totalHouseholds, building.getId());
			}

		} catch (Exception e) {
			log.warn("生成单元记录失败，楼栋ID: {}", building.getId(), e);
			throw new BusinessException("生成单元记录失败：" + e.getMessage());
		}
	}

	/**
	 * 更新楼栋的单元记录 根据单元数量变化动态调整单元记录
	 */
	private void updateUnitsForBuilding(Building building, List<Unit> existingUnits) {
		try {
			int newUnitCount = building.getUnitCount();
			int existingUnitCount = existingUnits.size();
			Long currentUserId = SecurityUtils.getCurrentUserId();

			// 如果单元数量有增加，需要增加新的单元记录
			if (newUnitCount > existingUnitCount) {
				List<Unit> newUnits = new ArrayList<>();
				int unitsPerFloor = building.getUnitsPerFloor() != null ? building.getUnitsPerFloor() : 2;

				for (int i = existingUnitCount + 1; i <= newUnitCount; i++) {
					Unit unit = new Unit();
					unit.setUnitNo(String.valueOf(i));
					unit.setUnitName(i + "单元");
					unit.setUnitCode(building.getBuildingNo() + "-" + i);
					unit.setBuildingId(building.getId());
					unit.setCommunityId(building.getCommunityId());
					unit.setFloorCount(building.getFloorCount());
					unit.setRoomCount(building.getFloorCount() * unitsPerFloor);
					unit.setHouseholdCount(0);
					unit.setHasElevator(0);
					unit.setElevatorCount(0);
					unit.setDoorAccessType(1);
					unit.setStatus(0);
					unit.setCreateBy(currentUserId);
					unit.setUpdateBy(currentUserId);

					newUnits.add(unit);
				}

				if (!newUnits.isEmpty()) {
					// 使用mapper直接保存
					for (Unit unit : newUnits) {
						unitMapper.insert(unit);
					}
					log.info("楼栋编辑成功，新增{}个单元记录，楼栋ID: {}", newUnits.size(), building.getId());
				}
			}

			// 更新所有现有单元的楼层数、房间数量等字段
			if (!existingUnits.isEmpty()) {
				int unitsPerFloor = building.getUnitsPerFloor() != null ? building.getUnitsPerFloor() : 2;

				for (Unit unit : existingUnits) {
					unit.setFloorCount(building.getFloorCount());
					unit.setRoomCount(building.getFloorCount() * unitsPerFloor);
					unit.setUpdateBy(currentUserId);
					unit.setUpdateTime(LocalDateTime.now());
				}

				// 使用mapper直接更新
				for (Unit unit : existingUnits) {
					unitMapper.updateById(unit);
				}
				log.info("楼栋编辑成功，更新{}个现有单元记录，楼栋ID: {}", existingUnits.size(), building.getId());
			}

			// 在单元数据更新完毕的时候，我们执行房户数据的更新
			int totalUpdatedHouseholds = 0;
			int unitsPerFloor = building.getUnitsPerFloor() != null ? building.getUnitsPerFloor() : 2;

			// 更新所有单元的房户数据（包括新增的单元）
			List<Unit> allUnits = unitMapper.selectByBuildingId(building.getId());
			for (Unit unit : allUnits) {
				int updatedCount = updateHouseholdsForUnit(unit.getId(), building.getId(),
						building.getFloorCount(), unitsPerFloor);
				totalUpdatedHouseholds += updatedCount;
			}

			log.info("楼栋编辑成功，已更新{}个单元的房户记录，新增房户数量：{}，楼栋ID: {}", allUnits.size(), totalUpdatedHouseholds,
					building.getId());

			// 注意：如果单元数量有减少，不删除原有单元记录，保持数据完整性

		} catch (Exception e) {
			log.warn("更新单元记录失败，楼栋ID: {}", building.getId(), e);
			throw new BusinessException("更新单元记录失败：" + e.getMessage());
		}
	}

	// ==================== 房户生成方法实现 ====================

	/**
	 * 为单元批量生成房户记录
	 */
	private int generateHouseholdsForUnit(Unit unit, Long buildingId, Integer floorCount, Integer unitsPerFloor) {
		log.info("为单元批量生成房户记录，单元ID：{}，楼栋ID：{}，楼层数：{}，每层户数：{}", unit.getId(), buildingId, floorCount, unitsPerFloor);
		
		try {
			if (unit.getId() == null || buildingId == null || floorCount == null || unitsPerFloor == null) {
				throw new BusinessException("参数不能为空");
			}
			
			if (floorCount <= 0 || unitsPerFloor <= 0) {
				throw new BusinessException("楼层数和每层户数必须大于0");
			}
			
			List<Household> households = new ArrayList<>();
			Long currentUserId = SecurityUtils.getCurrentUserId();
			
			// 二维数组循环创建房户对象
			// 第一层循环是楼栋的楼层数(从1开始)
			// 第二层循环是每层户数(从1开始)
			for (int floor = 1; floor <= floorCount; floor++) {
				for (int unitIndex = 1; unitIndex <= unitsPerFloor; unitIndex++) {
					Household household = new Household();
					
					// 房间号命名规则：{楼层号}{每层户数序号(需两位，不到两位前面补0)}
					String roomNumber = String.format("%d%02d", floor, unitIndex);
					
					// 房户编码默认跟房间号一致
					String householdCode = roomNumber;

					household.setHouseholdCode(householdCode);
					household.setCommunityId(unit.getCommunityId());
					household.setBuildingId(buildingId);
					household.setUnitId(unit.getId());
					household.setFloorNumber(floor);
					household.setRoomNumber(roomNumber);                    
					// 每户的面积（默认是单元面积除以每层户数）
					double ha = unit.getArea().doubleValue() / unitsPerFloor;
					household.setArea(BigDecimal.valueOf(ha));
					
					// 其他字段默认值设置
					household.setRoomType(1); // 默认一室
					household.setStatus(1); // 默认已入住状态
					household.setCreateBy(currentUserId);
					household.setUpdateBy(currentUserId);
					household.setCreateTime(LocalDateTime.now());
					household.setUpdateTime(LocalDateTime.now());
					household.setDeleted(0);
					household.setVersion(1); // 设置版本号
					
					households.add(household);
				}
			}
			
			// 批量保存房户记录
			if (!households.isEmpty()) {
				householdMapper.batchInsert(households);
				log.info("单元房户生成成功，单元ID：{}，生成房户数量：{}", unit.getId(), households.size());
				return households.size();
			}
			
			return 0;
			
		} catch (Exception e) {
			log.error("为单元批量生成房户记录失败，单元ID：{}", unit.getId(), e);
			throw new BusinessException("生成房户记录失败：" + e.getMessage());
		}
	}

	/**
	 * 更新单元的房户记录
	 */
	private int updateHouseholdsForUnit(Long unitId, Long buildingId, Integer floorCount, Integer unitsPerFloor) {
		log.info("更新单元的房户记录，单元ID：{}，楼栋ID：{}，楼层数：{}，每层户数：{}", unitId, buildingId, floorCount, unitsPerFloor);
		
		try {
			if (unitId == null || buildingId == null || floorCount == null || unitsPerFloor == null) {
				throw new BusinessException("参数不能为空");
			}
			
			if (floorCount <= 0 || unitsPerFloor <= 0) {
				throw new BusinessException("楼层数和每层户数必须大于0");
			}
			
			// 检查单元是否存在
			Unit unit = unitMapper.selectById(unitId);
			if (unit == null) {
				throw new BusinessException("单元不存在");
			}
			
			Long currentUserId = SecurityUtils.getCurrentUserId();
			int updatedCount = 0;
			
			// 二维数组循环更新房户信息
			// 第一层循环是楼栋的楼层数(从1开始)
			// 第二层循环是每层户数(从1开始)
			for (int floor = 1; floor <= floorCount; floor++) {
				for (int unitIndex = 1; unitIndex <= unitsPerFloor; unitIndex++) {
					// 房间号命名规则：{楼层号}{每层户数序号(需两位，不到两位前面补0)}
					String roomNumber = String.format("%d%02d", floor, unitIndex);
					
					// 查询是否已存在该房间号的房户
					List<Household> existingHouseholds = householdMapper.selectByRoomNumber(roomNumber, unitId);
					
					if (existingHouseholds.isEmpty()) {
						// 如果不存在，创建新的房户记录
						Household household = new Household();
						
						// 房户编码默认跟房间号一致
						String householdCode = roomNumber;

						household.setHouseholdCode(householdCode);
						household.setCommunityId(unit.getCommunityId());
						household.setBuildingId(buildingId);
						household.setUnitId(unitId);
						household.setFloorNumber(floor);
						household.setRoomNumber(roomNumber);                    
						// 每户的面积（默认是单元面积除以每层户数）
						double ha = unit.getArea().doubleValue() / unitsPerFloor;
						household.setArea(BigDecimal.valueOf(ha));
						
						// 其他字段默认值设置
						household.setRoomType(1); // 默认一室
						household.setStatus(1); // 默认已入住状态
						household.setCreateBy(currentUserId);
						household.setUpdateBy(currentUserId);
						household.setCreateTime(LocalDateTime.now());
						household.setUpdateTime(LocalDateTime.now());
						household.setDeleted(0);
						household.setVersion(1); // 设置版本号
						
						householdMapper.insert(household);
						updatedCount++;
					}
				}
			}
			
			log.info("单元房户更新成功，单元ID：{}，新增房户数量：{}", unitId, updatedCount);
			return updatedCount;
			
		} catch (Exception e) {
			log.error("更新单元的房户记录失败，单元ID：{}", unitId, e);
			throw new BusinessException("更新房户记录失败：" + e.getMessage());
		}
	}
}
